use std::error::Error;
use std::io::{stdout, Write};
use std::sync::{Arc, Mutex};
use lazy_static::lazy_static;
use crate::lincni::convertion::{DNS, Interface, IPConfig, ResultInterface, Route};
// use crate::lincni::convertion::convert::{Converters};
use crate::lincni::error::Errors;
use serde::{Serialize,Deserialize};

static SUPPORT_VERSIONS:[&str;3] = [
    "0.3.0","0.3.1","0.4.0"
];

#[derive(Clone,Debug,Default,Serialize,Deserialize)]
pub struct Result040 {
    #[serde(rename="cniVersion")]
    pub cni_version:String,
    #[serde(skip_serializing_if = "Option::is_none",default)]
    pub interfaces:Option<Vec<Interface>>,
    #[serde(skip_serializing_if = "Option::is_none",default)]
    pub ips:Option<Vec<IPConfig>>,
    #[serde(skip_serializing_if = "Option::is_none",default)]
    pub routes:Option<Vec<Route>>,
    #[serde(skip_serializing_if = "Option::is_none",default)]
    pub dns:Option<DNS>,
    // #[serde(skip_serializing,skip_deserializing)]
    // converters:Arc<Converters>,
}

impl Result040 {
    pub fn new() -> Self {
        let mut res = Self::default();
        // res.converters = CONVERTERS.clone();

        res
    }

    pub fn print_result(&self) ->Result<(),Box<dyn Error>> {
        self.print()
    }
}

impl ResultInterface for Result040 {
    fn version(&self) -> String {
        self.cni_version.clone()
    }

    fn get_as_version(&mut self, version: String) -> Result<Box<dyn ResultInterface>, Box<dyn Error>> {
        if self.cni_version.is_empty() {
            self.cni_version = "0.4.0".to_string();
        }

        if self.cni_version.as_str() == version.as_str() {
            return Ok(Box::new(self.clone()));
        }

        Err(Errors::FromStr(format!("no converter for CNI result version")).to_dyn())
        // match self.cni_version.as_str() {
        //     "0.1.0" if SUPPORT_VERSIONS.contains(&version.as_str()) => {
        //
        //     },
        //     "0.2.0" if SUPPORT_VERSIONS.contains(&version.as_str()) => {
        //
        //     },
        //     "0.3.0" if SUPPORT_VERSIONS.contains(&version.as_str()) => {
        //
        //     },
        //     "0.3.0" if ["0.1.0", "0.2.0"].contains(&version.as_str()) => {
        //
        //     },
        //     "0.3.1" if SUPPORT_VERSIONS.contains(&version.as_str())  => {
        //
        //     },
        //     "0.3.1" if ["0.1.0", "0.2.0"].contains(&version.as_str())  => {
        //
        //     },
        //     "0.4.0" if ["0.3.0", "0.3.1"].contains(&version.as_str()) => {
        //
        //     },
        //     "0.4.0" if ["0.1.0", "0.2.0"].contains(&version.as_str()) => {
        //
        //     },
        //     _=> {
        //         return Err(Errors::FromStr(format!("no converter for CNI result version {} to {}", fromVersion, toVersion)).to_dyn());
        //     }
        // }

        // self.converters.convert(Box::new(self.clone()),version)
    }

    fn print(&self) -> Result<(), Box<dyn Error>> {
        self.print_to(Box::new(stdout()))
    }

    fn print_to(&self, mut w: Box<dyn Write>) -> Result<(), Box<dyn Error>> {
        let str = serde_json::to_string_pretty(self)?;
        w.write(str.as_bytes())?;

        Ok(())
    }
}


// fn convert_from_02x(from:,to:String) -> Result<Box<dyn ResultInterface>, Box<dyn Error>> {
//
// }

